package
{
	import browserUI.BrowserEvent;
	import browserUI.JSEvent;
	import browserUI.Key;
	import browserUI.Navbar;
	import browserUI.PopUpKeyboard;
	import browserUI.PopUpKeyboardEvent;
	import browserUI.UICommandEvent;
	import browserUI.WebBrowser;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.TransformGestureEvent;
	import flash.geom.Matrix;
	import flash.geom.PerspectiveProjection;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Transform;
	import flash.html.HTMLHost;
	import flash.html.HTMLLoader;
	import flash.net.SharedObject;
	import flash.net.URLRequest;
	import flash.net.registerClassAlias;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.ui.Keyboard;
	import flash.ui.Multitouch;
	import flash.ui.MultitouchInputMode;
	
	import settings.BitmapDataSerializer;
	import settings.Settings;
	
	
	public class MTBrowser extends Sprite
	{
		public var navBar:Navbar;
		public var keyboard:PopUpKeyboard;
		private var _tabs:Vector.<WebBrowser>;
		private var _currentTab:int;
		
		public static var currentSettings:Settings;
		
		public function MTBrowser()
		{
			super();
			Multitouch.inputMode=MultitouchInputMode.TOUCH_POINT;
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.align=StageAlign.TOP_LEFT;	
			
			currentSettings=Settings.loadSettings();
			
			navBar=new Navbar();
			navBar.addEventListener(BrowserEvent.BROWSE_COMMAND,function(event:BrowserEvent):void{
				_tabs[_currentTab].browseTo(event.url);
			});
			navBar.addEventListener(BrowserEvent.BACK_COMMAND,onBack);
			navBar.addEventListener(BrowserEvent.FORWARD_COMMAND,onForward);
			navBar.addEventListener(BrowserEvent.NEW_TAB_COMMAND,function(event:BrowserEvent):void{
				addTab();
				redraw();
			});
			navBar.addEventListener(UICommandEvent.SELECT_TAB,function(event:UICommandEvent):void{
				selectTab(event.id);
			});
			navBar.addEventListener(UICommandEvent.CLOSE_TAB,function(event:UICommandEvent):void{
				closeTab(event.id);
			});
			navBar.addEventListener(UICommandEvent.CREATE_FAVOURITE,function(event:UICommandEvent):void{
				if(currentSettings.favourites.length<9){
					var scale:Number=Math.min((400/3)/_tabs[_currentTab].width,100/_tabs[_currentTab].height);
					var bmpData:BitmapData=new BitmapData(_tabs[_currentTab].width,_tabs[_currentTab].height);
					bmpData.draw(_tabs[_currentTab]);
					var sBitmap:BitmapDataSerializer=new BitmapDataSerializer();
					sBitmap.writeBitmapData(smoothScale(bmpData,_tabs[_currentTab].width*scale,_tabs[_currentTab].height*scale));
					currentSettings.favouritesBitmapData.push(sBitmap);
					currentSettings.favourites.push(_tabs[_currentTab].html.location);
					Settings.saveSettings(currentSettings);
				}
			});
			addChild(navBar);
			
			keyboard=new PopUpKeyboard();
			addChild(keyboard);
			keyboard.addEventListener(PopUpKeyboardEvent.KEY_PRESS,onKeyPress);
			
			_tabs=new Vector.<WebBrowser>(4);
			addTab();
			
			stage.addEventListener(Event.RESIZE,onResize);
			stage.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE,onFocusChange);
		}
		
		
		
		private function addTab():void{
			var a:int;
			var tid:int=-1;
			for(var t:int=0;t<_tabs.length; t++)
				if(_tabs[t])
					a++;
				else
					tid=(tid==-1)?t:tid;
			if(a<4){
				var browser:WebBrowser=new WebBrowser();
				browser=new WebBrowser();
				browser.width=stage.stageWidth;
				browser.y=60;
				browser.height=stage.stageHeight-120;
				browser.tabID=tid;
				addChild(browser);
				browser.addEventListener(BrowserEvent.PAGE_LOADED,onPageLoaded);
				browser.addEventListener(JSEvent.INPUT_FOCUS,onInputFocus);
				browser.addEventListener(JSEvent.INPUT_BLUR,onInputBlur);
				_tabs[tid]=browser;
				navBar.addTab(browser.tabID);
				selectTab(tid);
				
				var browseCommand:BrowserEvent=new BrowserEvent(BrowserEvent.BROWSE_COMMAND);
				browseCommand.url=currentSettings.homeURL;
				navBar.dispatchEvent(browseCommand);
			}
		}
		
		public function selectTab(id:int):void{
			_tabs[_currentTab].visible=false;
			navBar.selectTab(id);
			navBar.url=_tabs[id].html.location;
			_tabs[id].visible=true;
			setChildIndex(_tabs[id],0);
			_currentTab=id;
			redraw();
		}
		
		public function closeTab(id:int):void{
			var a:int;
			for(var t:int=0;t<_tabs.length; t++)
				if(_tabs[t])
					a++;
			if(a>1){
				removeChild(_tabs[id]);
				_tabs[id]=null;
				for(var i:int=0; i<_tabs.length; i++){
					if(_tabs[i]){
						_currentTab=i;
						break;
					}
				}
				navBar.removeTab(id);
				selectTab(_currentTab);
				redraw();
			}
		}
		
		public function onInputFocus(event:JSEvent):void{
			keyboard.open=true;
		}
		
		public function onInputBlur(event:JSEvent):void{
			if(_tabs[_currentTab].hasFocus)
				keyboard.open=false;
		}
		
		public function onBack(event:BrowserEvent):void{
			_tabs[_currentTab].html.historyBack();
		}
		
		public function onForward(event:BrowserEvent):void{
			_tabs[_currentTab].html.historyForward();
		}
		
		public function onFocusChange(event:FocusEvent):void{
			if(keyboard.contains(event.relatedObject)){
				event.preventDefault();
				return
			}
			if(event.relatedObject is TextField){
				if(TextField(event.relatedObject).type==TextFieldType.INPUT)
					keyboard.open=true;
			}
			else
				keyboard.open=false;
			if(_tabs[_currentTab].contains(event.relatedObject))
				_tabs[_currentTab].hasFocus=true;
			else
				_tabs[_currentTab].hasFocus=false;
		}
		
		public function onKeyPress(event:PopUpKeyboardEvent):void{
			var textField:TextField=stage.focus as TextField;
			if(textField != null){
				handleKeyPress(event.keyID,textField);
				return;
			}
			if(_tabs[_currentTab].hasFocus){
				_tabs[_currentTab].handleKeyPress(event.keyID);
			}
		}
		
		private function handleKeyPress(keyID:String,textField:TextField):void{
			if(keyID.toUpperCase()==Key.ENTER){
				if(textField==navBar.urlInput){
					navBar.browseToURL();
				}
				return
			}
			if(keyID.toUpperCase()==Key.BACK){
				if(navBar.contains(textField)){
					if(textField.selectionBeginIndex==textField.selectionEndIndex)
						textField.text=textField.text.substring(0,textField.selectionBeginIndex-1)+textField.text.substring(textField.selectionEndIndex);
					else
						textField.text=textField.text.substring(0,textField.selectionBeginIndex)+textField.text.substring(textField.selectionEndIndex);
					textField.setSelection(textField.selectionBeginIndex,textField.selectionBeginIndex);
				}
				return
			}
			textField.text=textField.text.substring(0,textField.selectionBeginIndex)+keyID+textField.text.substring(textField.selectionEndIndex);
			textField.setSelection(textField.selectionBeginIndex+1,textField.selectionBeginIndex+1);
		}
		
		public function onPageLoaded(event:BrowserEvent):void{
			if(event.target is WebBrowser){
				if(WebBrowser(event.target).tabID==_currentTab){
					stage.focus=_tabs[_currentTab].html;
					_tabs[_currentTab].hasFocus=true;
					navBar.url=_tabs[_currentTab].html.location;
				}
				navBar.setTabTitle(WebBrowser(event.target).tabID,WebBrowser(event.target).html.window.document.title);
			}
		}
		
		public static function smoothScale(bitmapData:BitmapData,targetWidth:int,targetHeight:int):BitmapData{
			var cx:Number=targetWidth;
			var cy:Number=targetHeight;
			var nDoubles:int=0;
			while(cx<bitmapData.width){
				cx*=2;
				cy*=2;
				nDoubles++;
			}
			var initX:Number=cx/bitmapData.width;
			var initY:Number=cy/bitmapData.height;
			var bmpDat:BitmapData=bitmapData;
			var small:BitmapData=new BitmapData(bmpDat.width*initX,bmpDat.height*initY);
			small.draw(bmpDat,new Matrix(initX,0,0,initY));
			bmpDat=small;
			for(var i:int=0; i<nDoubles; i++){
				small=new BitmapData(bmpDat.width/2,bmpDat.height/2);
				small.draw(bmpDat,new Matrix(0.5,0,0,0.5),null,null,null,true);
				bmpDat=small;
			}
			return bmpDat;
		}
		
		private function redraw():void{
			navBar.width=stage.stageWidth;
			_tabs[_currentTab].width=stage.stageWidth;
			_tabs[_currentTab].height=stage.stageHeight-60;
			keyboard.width=stage.stageWidth;
			keyboard.height=Math.min(stage.stageHeight/2,550);
			keyboard.y=stage.stageHeight-keyboard.height;
		}
		
		public function onResize(event:Event):void{
			redraw();
		}
	}
}